﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CapaDeDominio;

namespace CapaDeDatos.EF
{
    public class ReservaDAO : IReservaDAO
    {

        #region IBaseDAO<Reserva,int> Members

        /// <summary>
        /// Crear Reserva
        /// </summary>
        /// <param name="ReservaACrear">Dominio Reserva</param>
        /// <returns>Dominio Reserva</returns>
        public Reserva Crear(Reserva ReservaACrear)
        {
            using (EFContext db = new EFContext(ConexionUtil.ObtenerCadena()))
            {
                int? codigo = db.Locales.Select(l => (int?)l.Codigo).Max();
                ReservaACrear.Codigo = (codigo ?? 0) + 1;
                db.Clientes.Attach(ReservaACrear.Cliente);
                db.Salas.Attach(ReservaACrear.Sala);
                db.Reservas.Add(ReservaACrear);
                db.SaveChanges();
            }
            return Obtener(ReservaACrear.Codigo);
        }

        /// <summary>
        /// Obtener Reserva
        /// </summary>
        /// <param name="Codigo">Codigo de la Reserva</param>
        /// <returns></returns>
        public Reserva Obtener(int Codigo)
        {
            using (EFContext db = new EFContext(ConexionUtil.ObtenerCadena()))
            {
                var reserva = from l in db.Reservas
                               .Include("Cliente")
                               .Include("Sala")
                               .Include("InstrumentosAdicionales")
                               .Include("ServiciosAdicionales")
                              where l.Codigo == Codigo
                              select l;

                
                               
                return reserva.SingleOrDefault();
            }
        }

        /// <summary>
        /// Listar Reserva
        /// </summary>
        /// <returns>Colleccion de Reserva</returns>
        public ICollection<Reserva> ListarTodos()
        {
            using (EFContext db = new EFContext(ConexionUtil.ObtenerCadena()))
            {
                var resultado = from l in db.Reservas
                               .Include("Cliente")
                               .Include("Sala")
                               .Include("InstrumentosAdicionales")
                               .Include("ServiciosAdicionales")
                                select l;
                return resultado.ToList();
            }
        }

        #endregion

        /// <summary>
        /// Busca las salas que han sido reservadas por fecha y hora
        /// </summary>
        /// <param name="fecha"></param>
        /// <param name="hora"></param>
        /// <returns></returns>
        public ICollection<Reserva> ListarSalasReservadasXFechaHora(DateTime fecha, int hora)
        {
            using (EFContext db = new EFContext(ConexionUtil.ObtenerCadena()))
            {
                var resultado = from l in db.Reservas
                               .Include("Cliente")
                               .Include("Sala")
                               .Include("InstrumentosAdicionales")
                               .Include("ServiciosAdicionales")
                                select l;

                if (hora != null)
                    resultado = from l in resultado
                                where (l.Hora_inicio == hora)
                                select l; 

                if (fecha.Year > 1900)
                    resultado = from l in resultado
                                where (l.Fecha_inicio == fecha)
                                select l;      

                return resultado.ToList();
            }
        }


        /// <summary>
        /// Permite buscar las reservas de una sala en una fecha para su preparacion
        /// </summary>
        /// <param name="fechaReserva"></param>
        /// <param name="sala"></param>
        /// <returns></returns>
        public ICollection<Reserva> ListarXBusquedaReserva(DateTime fechaReserva, Sala sala)
        {
            using (EFContext db = new EFContext(ConexionUtil.ObtenerCadena()))
            {
                var resultado = from l in db.Reservas
                               .Include("Cliente")
                               .Include("Sala")
                               .Include("InstrumentosAdicionales")
                               .Include("ServiciosAdicionales")
                               select l;

                if (sala != null) 
                       resultado = from l in resultado 
                            where (l.Sala.Codigo == sala.Codigo) 
                            select l;

                if (fechaReserva.Year > 1900)
                    resultado = from l in resultado
                            where (l.Fecha_inicio == fechaReserva)
                            select l;      

                return resultado.ToList();
            }
        }

        public void Eliminar(Reserva itemEliminar)
        {
            using (EFContext db = new EFContext(ConexionUtil.ObtenerCadena()))
            {
                Reserva reserva = (from s in db.Reservas
                                 .Include("Cliente")
                                 .Include("Sala")
                                 .Include("InstrumentosAdicionales")
                                 .Include("ServiciosAdicionales")
                                   where s.Codigo == itemEliminar.Codigo
                                   select s).Single();                 

                db.Reservas.Remove(reserva);
                db.SaveChanges();
            }
        }

        public void AsignarInstrumentos(int codigo, ICollection<Instrumento> instrumentos)
        {
            using (EFContext db = new EFContext(ConexionUtil.ObtenerCadena()))
            {
                Reserva reservaAModificar = db.Reservas.Single(l => l.Codigo == codigo);
                reservaAModificar.InstrumentosAdicionales = new List<Instrumento>();
                foreach (Instrumento instrumento in instrumentos)
                    reservaAModificar.InstrumentosAdicionales.Add(db.Instrumentos.Single(l => l.Codigo == instrumento.Codigo));
                db.SaveChanges();
            }
        }

        public void AsignarServicios(int codigo, ICollection<Servicio> servicios)
        {
            using (EFContext db = new EFContext(ConexionUtil.ObtenerCadena()))
            {
                Reserva reservaAModificar = db.Reservas.Single(l => l.Codigo == codigo);
                reservaAModificar.ServiciosAdicionales = new List<Servicio>();
                foreach (Servicio servicio in servicios)
                    reservaAModificar.ServiciosAdicionales.Add(db.Servicios.Single(l => l.Codigo == servicio.Codigo));
                db.SaveChanges();

                /*Sala salaAModificar = db.Salas.Single(l => l.Codigo == codigo);
                salaAModificar.Servicios = servicio;
                db.SaveChanges();*/
            }
        }
    }
}